import styles from "./MultiCheck.scss";
import React, { useCallback, useEffect, useMemo } from "react";
import Checkbox from "../component/checkbox/index";
const CheckboxGroup = Checkbox.Group;

export type Option = {
  label: string;
  value: string;
  checked?: boolean;
};

/**
 * Notice:
 * 1. There should be a special `Select All` option with checkbox to control all passing options
 * 2. If columns > 1, the options should be placed from top to bottom in each column
 *
 * @param {string} label - the label text of this component
 * @param {Option[]} options - options
 * @param {string[]} values - default checked option values
 * @param {number} columns - default value is 1
 * @param {Function} onChange - when checked options are changed,
 *                             they should be passed to outside
 */
interface MultiCheckProps {
  label?: string;
  options: Option[];
  columns?: number;
  values?: string[];
  onChange?: (options: Option[]) => void;
}

const MultiCheck: React.FunctionComponent<MultiCheckProps> = ({
  options,
  values = [],
  onChange,
  label,
}): JSX.Element => {
  const [checkedList, setCheckedList] = React.useState(values);
  const [checkAll, setCheckAll] = React.useState(
    checkedList.length === options.length
  );

  useEffect(() => {
    const selectedValues: Option[] = [];
    options.forEach((option) => {
      if (checkedList?.indexOf(option.value) > -1) {
        selectedValues.push(option);
      }
    });
    onChange?.(selectedValues);
  }, [checkedList]);

  const getValues = useMemo(() => {
    return options.map((option) => {
      return option.value;
    });
  }, [options]);

  const selectAll = (option: Option) => {
    setCheckAll(!!option?.checked);
    setCheckedList(option.checked ? getValues : []);
  };

  const onGroupChange = useCallback(
    (option: Option) => {
      let list = [...checkedList];
      if (option.checked) {
        list.push(option.value);
      } else {
        list = list.filter((l) => l !== option.value);
      }
      setCheckAll(list.length === options.length);
      setCheckedList(list);
    },
    [checkedList]
  );
  return (
    <div className={styles.MultiCheck}>
      <h3 className={styles.Title}>{label}</h3>
      <div className={styles.CheckboxContainer}>
        <CheckboxGroup
          options={options}
          values={checkedList}
          onChange={onGroupChange}
        >
          <Checkbox
            value={"Select All"}
            onChange={selectAll}
            name={"Select All"}
            checked={checkAll}
          />
        </CheckboxGroup>
      </div>
    </div>
  );
};

export default MultiCheck;
